<template>
  <div v-if="windowVisible" :class="['intelligentAssistant', pageSize]">
    <div class="title">
      <div class="name">
        智能助手<span v-if="menuBar && currentPage != 'map'">({{ menuBar }})</span>
      </div>
      <div class="operate">
        <div class="el-icon-minus" @click="minimize"></div>
        <div class="iconfont icon-winfo-icon-zuidahua" v-if="pageSize == 'small'" @click="pageSize = 'lager'"></div>
        <div class="iconfont icon-3zuidahua-3" v-else @click="pageSize = 'small'"></div>
        <div class="el-icon-close" @click="close"></div>
      </div>
    </div>
    <div class="questions" v-loading="conLoading">
      <div class="top" ref="windowTop" @click="leftPanelVisible = false">
        <div class="scollBox" ref="scollBox">
          <div v-for="(item, index) in content" :key="index">
            <div class="messageInfo" :class="{ messageInfoRight: item.sender == 'user' }">
              <img v-if="item.sender == 'assistant'" src="@/assets/image/waterMap/robot.png" alt="" />
              <img v-else src="@/assets/image/waterMap/user.png" alt="" />
              <div v-if="item.text" class="text">
                <div v-html="item.text"></div>
                <el-rate
                  v-if="rateVisibleFun(item, index)"
                  v-model="item.rateValue"
                  @change="handleRate(item)"
                  show-text
                  :colors="['#99A9BF', '#F7BA2A', '#f1ab42']">
                </el-rate>
              </div>
              <div v-else v-loading="loadingObj[index]" element-loading-spinner="el-icon-loading" class="askLoading"></div>
            </div>
            <template v-if="item?.fileList?.length">
              <div class="fileRelated" v-for="(ele, i) in item.fileList" :key="index + ele.file_name + i">
                <fileCard :info="ele" @priview="priviewFile"></fileCard>
                <i v-if="ele.content" @click="relatedContents(item, ele)" class="iconfont icon-zhushi" title="文件相关内容"></i>
              </div>
            </template>
          </div>
        </div>
      </div>
      <div class="bottom">
        <div class="left">
          <img @click="handleMenu" src="@/assets/image/window/menu.png" alt="" />
          <img @click="visibleHistory" src="@/assets/image/window/history.png" alt="" />
        </div>
        <div class="center">
          <el-input
            v-model="askInput"
            placeholder="请输入内容"
            @keyup.enter.native="sendMessageMultibase"
            @focus="leftPanelVisible = false"></el-input>
          <img class="voice" src="@/assets/image/window/voice.png" alt="" />
        </div>
        <div class="right">
          <el-button @click="sendMessageMultibase" class="button-gradient" size="medium">发送</el-button>
          <i @click="newAction" title="新建会话" class="el-icon-circle-plus-outline"></i>
        </div>
      </div>
    </div>
    <!--文件相关片段  -->
    <parentDialog title="文件相关片段" :visible.sync="dialogVisible" v-if="dialogVisible">
      <p class="relatedFragment">{{ relatedFragment }}</p>
    </parentDialog>

    <!-- 预览 -->
    <parentDialog title="详情" :visible.sync="previewVisible" v-if="previewVisible" width="60%" height="95%">
      <component :is="fileType" :info="fileInfo" v-if="previewVisible"></component>
    </parentDialog>

    <!-- 菜单栏 -->
    <div class="menuBox" @click.stop="() => {}" v-if="menuVisible">
      <el-cascader-panel :options="cascaderOptions" @change="cascaderblur"></el-cascader-panel>
    </div>
    <div class="menuList" v-if="leftPanelVisible" :style="{ width: leftPanelWidth }">
      <div class="title">{{ leftPanelTitle }}</div>
      <selectionKnowledge v-if="leftPanelTitle == '选择文件库'"></selectionKnowledge>
      <dialogueHistory v-else-if="leftPanelTitle == '对话记录'" @resetContent="resetContent"></dialogueHistory>
    </div>
  </div>
  <div class="bitmap" @click="windowVisible = true" v-else>
    <img src="@/assets/image/window/bitmap.png" alt="" />
    <img class="outLine" src="@/assets/image/window/bitmap-outLine.png" alt="" />
  </div>
</template>

<script>
import { knowledgeBaseChat, knowledgeChatMultibase, QAmain, markZhishui } from "@/api/chartWindow.js";
import fileCard from "@/components/intelligentAssistant/fileCard.vue"; // 文件显示
import txt from "@/components/priviewFile/txt.vue";
import pdf from "@/components/priviewFile/pdf.vue";
import docx from "@/components/priviewFile/docx.vue";
import xlsx from "@/components/priviewFile/xlsx.vue";
import parentDialog from "@/components/dialog/parentDialog.vue"; // 文件相关片段
import selectionKnowledge from "./selectionKnowledge";
import dialogueHistory from "@/components/intelligentAssistant/dialogueHistory.vue";

import MarkdownIt from "markdown-it";

export default {
  name: "chatWindow",
  components: { fileCard, parentDialog, txt, pdf, docx, xlsx, selectionKnowledge, dialogueHistory },
  props: {
    currentPage: {
      type: String,
      default: "map",
    },
  },
  data() {
    // html：是否允许在Markdown文本中使用HTML标签，默认值为false。
    // breaks：是否将连续的换行符转换为<br>标签，默认值为false。
    // typographer：是否启用智能引号和破折号等Typographer功能，默认值为false。
    // linkify：是否将URL转换为链接，默认值为false。
    // highlight：代码高亮函数。
    let md = new MarkdownIt()
      .set({ html: true, breaks: true, typographer: true, linkify: true })
      .set({ highlight: (code, lang) => highlight(code, lang) });
    return {
      content: [
        {
          sender: "assistant",
          text: "这里是水利部知识平台智能助手，有问题可以随时问我哦～",
        },
      ],
      cascaderOptions: [
        {
          value: "ssfw",
          label: "搜索范围",
        },
      ],
      askInput: "",
      windowVisible: false,
      leftPanelVisible: false,
      leftPanelTitle: "选择文件库",
      previewVisible: false,
      fileInfo: null,
      fileType: "",
      dialogVisible: false,
      relatedFragment: "",
      tempKnowledge: null,
      searchRound: "全局搜索",
      menuVisible: false,
      pageSize: "small",
      leftPanelWidth: "25%",
      sessionId: null,
      loadingObj: {},
      md: md,
      historyList: [],
    };
  },
  computed: {
    selectionknowledgev() {
      // this.tempKnowledge = null;
      let arr = this.$store.state.selectionKnowledge;
      return [...arr.map(v => v.id).filter(v => v != "个人知识库")];
    },
    menuBar() {
      let name = "全局问答";
      let arr = this.$store.state.selectionKnowledge;
      let list = [...arr.map(v => v.label)];
      if (list.includes("公共文档库") && list.length > 1) name = "全局+个人";
      else if (list.includes("公共文档库")) name = "全局问答";
      else if (list.includes(`dev-cx-temp-${localStorage.getItem("userName")}`)) name = "临时问答";
      else name = "个人问答";
      return name;
    },
    conLoading() {
      return this.$store.state.overallLoading;
    },
  },

  mounted() {
    this.$Bus.$on("batchQuestioning", name => {
      if (name) {
        this.$store.commit("toggle_selectionKnowledge", [
          {
            id: name,
            label: `dev-cx-temp-${localStorage.getItem("userName")}`,
          },
        ]);
      }
      this.windowVisible = true;
    });
    this.$Bus.$on("handleList", item => {
      this.askInput = `查询pn_code为${item.pn_code}的${item.pn_name}详情`;
      this.sendMessageMultibase();
      this.windowVisible = true;
    });
  },
  methods: {
    // 评分提交
    handleRate(item) {
      let { sessionId, gmtModified, rateValue: mark } = item;
      markZhishui({ sessionId, gmtModified, mark })
        .then(result => {
          if (result.code == 200) this.$message.success(result.msg);
          else this.$message.error(result.msg);
        })
        .catch(err => {
          console.log(err);
        });
    },
    // 对话记录
    visibleHistory() {
      this.leftPanelTitle = "对话记录";
      this.leftPanelWidth = "80%";
      this.leftPanelVisible = true;
    },
    cascaderblur(item) {
      this.menuVisible = false;
      if (item[0] == "ssfw") {
        this.leftPanelTitle = "选择文件库";
        this.leftPanelWidth = "25%";
        this.leftPanelVisible = true;
      }
    },
    newAction() {
      this.sessionId = null;
      this.content = [
        {
          sender: "assistant",
          text: "这里是水利部知识平台智能助手，有问题可以随时问我哦～",
        },
      ];
    },
    // 历史记录更新
    resetContent(item, sessionId) {
      this.sessionId = sessionId;
      this.history = item.map(v => {
        return {
          role: item.sender,
          content: v.text,
        };
      });
      this.content = item.map(v => {
        return {
          ...v,
          text: this.handleMackdown(v.text),
        };
      });
      this.getScollHeight();
    },
    // 文件预览
    priviewFile(info) {
      this.previewVisible = true;
      this.fileInfo = info;
      this.fileType = info.file_url.split(".").at(-1);
    },
    // 文件相关内容弹窗
    relatedContents(item, fileContent) {
      console.log(item);
      this.relatedFragment = fileContent.content;
      this.dialogVisible = true;
    },
    // 知识库问答
    sendMessageMultibase() {
      let input = this.askInput.replace(/\r|\n/gi, "");
      if (!input) return;
      this.askInput = "";
      // let history = this.content.slice(-10);
      // history = history.map(item => {
      //   return {
      //     role: item.sender == "assistant" ? "assistant" : "user",
      //     content: item?.text || "",
      //   };
      // });

      this.historyList.push({
        role: "user",
        content: input,
      });
      this.content.push({
        sender: "user",
        text: input,
      });
      this.content.push({
        sender: "assistant",
      });
      // this.loading = true
      this.getScollHeight();
      let index = this.content.length - 1;
      this.loadingObj[index] = true;
      console.log(this.currentPage, "this.currentPagethis.currentPagethis.currentPage");
      // let api = this.currentPage == "map" ? QAmain : knowledgeChatMultibase;
      QAmain({
        sessionId: this.sessionId,
        query: input,
        kbIds: this.tempKnowledge || this.selectionknowledgev,
        history: this.historyList.slice(-10),
      })
        .then(result => {
          // this.loading = false
          this.loadingObj[index] = false;
          this.sessionId = this.sessionId || result?.data?.sessionId;
          this.historyList.push({
            role: "assistant",
            content: result?.data?.answer || "",
          });
          let obj = {
            sender: "assistant",
            text: this.handleMackdown(result?.data?.answer || ""),
            fileList: [],
          };
          if (result.code == 200) {
            obj.rateValue = 0;
            obj.sessionId = this.sessionId;
            obj.gmtModified = result?.data?.gmtCreated;
            if (result.data.jsonResult) {
              // if (result.data.jsonResult.includes("成功")) {
              this.$emit("panelData", result.data);
              // } else {
              //   result.data.jsonResult = JSON.parse(result.data.jsonResult)
              //   obj.text = result.data.jsonResult.responseMsg || result.data.jsonResult.errorMsg
              // }
            } else {
              if (!result.data?.docs?.includes("未找到相关文档")) {
                let docs = JSON.parse(result.data?.docs || "[]");
                //判断是否有关联文件
                let fileList = [];
                (docs || []).forEach(item => {
                  let obj = fileList.find(v => v.file_name == item.file_name);
                  if (!obj) fileList.push(item);
                });
                obj.fileList = fileList;
              } else obj.fileList = [];
            }
          } else {
            obj.text = "暂时无法查询，请稍后再试！";
          }
          this.$set(this.content, index, obj);
          delete this.loadingObj[index];
          this.getScollHeight();
        })
        .catch(err => {
          this.content[index].text = "请求超时，请稍后再试！";
          this.loadingObj[index] = false;
          delete this.loadingObj[index];
          console.log(this.loadingObj, index);
          console.log(err);
        });
    },
    getScollHeight() {
      this.$nextTick(() => {
        this.$refs.windowTop.scrollTop = this.$refs?.scollBox?.offsetHeight;
      });
    },
    minimize() {
      this.windowVisible = false;
      this.leftPanelVisible = false;
    },
    close() {
      this.windowVisible = false;
      this.leftPanelVisible = false;
    },
    handleMenu() {
      if (this.currentPage == "map") return;
      this.menuVisible = !this.menuVisible;
    },

    handleMackdown(markdownText) {
      let html = markdownText
        .replace(/`/gi, "")
        .split("\n")
        .reduce((prev, cur, index, arr) => {
          return this.md.render(prev) + (this.md.render(cur) || cur);
        }, "");
      return html;
    },

    rateVisibleFun(item, index) {
      return item.sender == "assistant" && index != 0 && (item.rateValue || item.rateValue == 0) && !item.text.includes("连接超时");
    },
  },
};
</script>
<style lang="scss" scoped>
.intelligentAssistant {
  position: fixed;
  bottom: 20px;
  right: 20px;
  width: 578px;
  height: 522px;
  background: #f3f4f6;
  border-radius: 10px;
  z-index: 99;
  &.lager {
    height: 90%;
  }
  .title {
    font-size: 16px;
    font-weight: 600;
    color: #ffffff;
    line-height: 42px;
    text-align: left;
    padding: 0px 15px;
    background: linear-gradient(205deg, #6491d9 0%, #3458b2 100%);
    border-radius: 10px 10px 0px 0px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    .operate {
      display: flex;
      justify-content: space-between;
      font-size: 20px;
      display: flex;
      align-items: center;
      div {
        cursor: pointer;
        margin: 0px 5px;
      }
    }
  }
  .questions {
    width: 100%;
    height: calc(100% - 42px);
    border-radius: 10px;
    background: #f3f4f6;
    .top {
      height: calc(100% - 45px);
      border-bottom: 2px solid rgba(0, 20, 45, 0.15);
      padding: 10px 10px;
      box-sizing: border-box;
      overflow: auto;
      .messageInfo {
        margin-top: 20px;
        display: flex;
        font-size: 14px;
        > img {
          width: 32px;
          height: 32px;
          margin-right: 5px;
          border-radius: 50%;
        }
        .text {
          line-height: 25px;
          padding: 5px 15px;
          border-radius: 20px 20px 20px 0px;
          background: rgba(30, 104, 231, 0.17);
          text-align: left;
          max-width: 77%;
          .el-rate {
            text-align: right;
          }
        }
      }
      .messageInfoRight {
        flex-direction: row-reverse;
        .text {
          border-radius: 20px 20px 0px 20px;
          text-align: left;
          max-width: 77%;
        }
        > img {
          margin-left: 5px;
        }
      }
      .fileRelated {
        display: flex;
        align-items: center;
        text-align: left;
        > i {
          color: #c0c0c0;
          display: block;
          margin-left: 5px;
          cursor: pointer;
        }
      }
      ::v-deep .fileCard {
        margin-left: 42px;
      }
      ::v-deep .el-icon-loading {
        margin-top: 15px;
      }
    }
    .bottom {
      height: 45px;
      padding: 0px 10px;
      box-sizing: border-box;
      display: flex;
      justify-items: flex-end;
      align-items: center;
      width: calc(100% - 5px);
      justify-content: space-between;
      .left {
        display: flex;
        align-items: center;
        img {
          width: 22px;
          height: 22px;
          margin: 0px 8px;
          cursor: pointer;
        }
      }
      .center {
        position: relative;
        width: 100%;
        ::v-deep .el-input__inner {
          height: 35px;
          border: none;
          border-radius: 5px;
        }
        .voice {
          position: absolute;
          top: 10px;
          right: 10px;
          cursor: pointer;
        }
        > img {
          width: 16px;
          height: 16px;
        }
      }
      .right {
        display: flex;
        align-items: center;
        margin-left: 8px;
        i {
          font-size: 18px;
          font-weight: bold;
          color: #909399;
          margin-left: 5px;
          cursor: pointer;
        }
      }
    }
  }
  .menuList {
    // width: 50%;
    // width: 80px;
    // height: 100%;
    position: absolute;
    bottom: 0px;
    left: 0px;
    transform: translateX(-100%);
    border-radius: 11px;
    background: #fff;
    padding: 10px 0px 10px 5px;
    height: calc(100%);
    box-sizing: border-box;
    border: 1px solid rgba(100, 120, 145, 0.1);
    // .el-tree {
    //   background: #f3f4f6;
    // }
    .title {
      width: calc(100% + 7px);
      margin-left: -6px;
      margin-top: -11px;
      box-sizing: border-box;
      padding-left: 12px;
    }
  }
  .menuBox {
    position: absolute;
    bottom: 45px;
    left: 0px;
    .el-cascader-panel {
      text-align: left;
      background: #fff;
    }
    ::v-deep .el-cascader-menu__wrap {
      height: auto;
    }
  }
}
.bitmap {
  position: fixed;
  bottom: 50px;
  right: 30px;
  cursor: pointer;
  z-index: 99;
  :nth-child(1) {
    width: 110px;
    height: 109px;
    transition: all 1s;
    &:hover {
      transform: scale(1.1);
    }
  }
  .outLine {
    width: 126px;
    height: 126px;
    position: absolute;
    top: -11px;
    left: -8px;
    transition: all 1s;
    &:hover {
      transform: scale(1.1) rotate(45deg);
    }
  }
}
</style>
